package com.element.sentinel.resource;

import com.alibaba.cloud.commons.lang.StringUtils;
import com.element.sentinel.constant.RuleTypeEnum;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.env.EnvironmentPostProcessor;
import org.springframework.core.env.ConfigurableEnvironment;
import org.springframework.core.env.PropertiesPropertySource;
import org.springframework.stereotype.Component;

import java.util.Properties;

@Component
public class SentinelEnvironmentPostProcessor implements EnvironmentPostProcessor {

    private static final String SENTINEL_NAME = "element.sentinel";
    private static final String SENTINEL_ENABLE = "sentinel.enable";

    private static final String SENTINEL_TRANSPORT_DASHBOARD = "sentinel.transport.dashboard";
    private static final String SENTINEL_DATASOURCE_URL = "sentinel.datasource.url";
    private static final String SENTINEL_DATASOURCE_NAMESPACE = "sentinel.datasource.namespace";

    private static final String SENTINEL_DATASOURCE_DEFAULT = "{default}";
    private static final String SENTINEL_DATASOURCE_DEFAULT_DATA_ID = "sentinel.datasource.{default}.data-id";
    private static final String SENTINEL_DATASOURCE_DEFAULT_GROUP_ID = "sentinel.datasource.{default}.group-id";

    @Override
    public void postProcessEnvironment(ConfigurableEnvironment environment, SpringApplication application) {
        boolean hasEnable = environment.containsProperty(SENTINEL_ENABLE);
        if (!hasEnable) {
            return;
        }
        boolean enable = environment.getProperty(SENTINEL_ENABLE, Boolean.class, false);
        if (!enable) {
            return;
        }
        Properties properties = new Properties();
        // 初始化建立Sentinel客户端连接
        initDashboard(environment, properties);

        String url = environment.getProperty(SENTINEL_DATASOURCE_URL);
        if (StringUtils.isEmpty(url)) {
            return;
        }
        String namespace = environment.getProperty(SENTINEL_DATASOURCE_NAMESPACE);
        if (StringUtils.isEmpty(namespace)) {
            return;
        }
        // 初始化限流规则
        initRule(environment, properties, url, namespace);
        environment.getPropertySources().addFirst(new PropertiesPropertySource(SENTINEL_NAME, properties));
        System.setProperty(SENTINEL_DATASOURCE_URL, url);
        System.setProperty(SENTINEL_DATASOURCE_NAMESPACE,namespace);
    }


    private void initDashboard(ConfigurableEnvironment environment, Properties properties) {
        boolean hasDashboard = environment.containsProperty(SENTINEL_TRANSPORT_DASHBOARD);
        if (!hasDashboard) {
            return;
        }
        String dashboard = environment.getProperty(SENTINEL_TRANSPORT_DASHBOARD, String.class);
        if (StringUtils.isEmpty(dashboard)) {
            return;
        }
        properties.setProperty("spring.cloud.sentinel.eager", "true");
        properties.setProperty("spring.cloud.sentinel.log.dir", "./logs/sentinel");
        properties.setProperty("spring.cloud.sentinel.log.switch-pid", "true");
        properties.setProperty("spring.cloud.sentinel.transport.port", "8719");
        properties.setProperty("spring.cloud.sentinel.transport.heartbeatIntervalMs", "30");
        properties.setProperty("spring.cloud.sentinel.transport.dashboard", dashboard);
    }

    private void initRule(ConfigurableEnvironment environment, Properties properties, String url, String namespace) {
        for (RuleTypeEnum ruleTypeEnum : RuleTypeEnum.values()) {
            String dataIdKey = SENTINEL_DATASOURCE_DEFAULT_DATA_ID.replace(SENTINEL_DATASOURCE_DEFAULT, ruleTypeEnum.getRuleTypeId());
            String dataId = environment.getProperty(dataIdKey);
            if (StringUtils.isEmpty(dataId)) {
                continue;
            }
            String groupIdKey = SENTINEL_DATASOURCE_DEFAULT_GROUP_ID.replace(SENTINEL_DATASOURCE_DEFAULT, ruleTypeEnum.getRuleTypeId());
            String groupId = environment.getProperty(groupIdKey);
            if (StringUtils.isEmpty(groupId)) {
                continue;
            }
            properties.setProperty(("spring.cloud.sentinel.datasource." + ruleTypeEnum.getRuleTypeId() + ".nacos.server-addr"), url);
            properties.setProperty(("spring.cloud.sentinel.datasource." + ruleTypeEnum.getRuleTypeId() + ".nacos.namespace"), namespace);
            properties.setProperty(("spring.cloud.sentinel.datasource." + ruleTypeEnum.getRuleTypeId() + ".nacos.data-id"), dataId);
            properties.setProperty(("spring.cloud.sentinel.datasource." + ruleTypeEnum.getRuleTypeId() + ".nacos.group-id"), groupId);
            properties.setProperty(("spring.cloud.sentinel.datasource." + ruleTypeEnum.getRuleTypeId() + ".nacos.rule-type"), ruleTypeEnum.getRuleType());
        }
    }
}